package com.rkc.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.rkc.config.AlipayConfiguration;
import com.rkc.enums.ProductOrderPayTypeEnum;
import com.rkc.service.ProductOrderService;
import com.rkc.utils.JsonData;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @author `RKC`
 * @date 2022/3/7 16:06
 */
@Slf4j
@Api("订单支付回调通知接口")
@Controller
@RequestMapping("/api/callback/order/v1")
public class OrderPayCallbackController {

    @Autowired
    private ProductOrderService productOrderService;

    /**
     * 支付宝支付成功的回调接口，由支付宝调用
     * @param request
     * @param response
     * @return
     */
    @PostMapping("alipay")
    public String alipayCallback(HttpServletRequest request, HttpServletResponse response) {
        //将异步通知中收到的所有参数转换为Map进行存储
        Map<String, String> paramsMap = convertRequestParamsToMap(request);
        log.info("支付宝回调通知结果：{}", paramsMap);
        //调用sdk验证签名
        try {
            if (AlipaySignature.rsaCheckV1(paramsMap, AlipayConfiguration.ALIPAY_PUB_KEY, AlipayConfiguration.CHARSET, AlipayConfiguration.SIGN_TYPE)) {
                JsonData res = productOrderService.handleOrderCallback(ProductOrderPayTypeEnum.ALIPAY, paramsMap);
                if (res.getCode() == 0) {
                    //通知结果确认成功，支付宝返回“success”字符串，否则会一直通知，如果8次都没返回success就认为交易失败
                    return "success";
                }
            }

        } catch (AlipayApiException e) {
            log.info("支付宝回调验证签名失败：{}", e.toString());
        }
        return "failure";
    }

    /**
     * 将request中的参数转换成Map
     * @param request
     * @return
     */
    private static Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {
        Map<String, String> paramsMap = new HashMap<>(16);
        Set<Map.Entry<String, String[]>> entrySet = request.getParameterMap().entrySet();
        for (Map.Entry<String, String[]> entry : entrySet) {
            String name = entry.getKey();
            String[] values = entry.getValue();
            int size = values.length;
            if (size == 1) {
                paramsMap.put(name, values[0]);
            } else {
                paramsMap.put(name, "");
            }
        }
        return paramsMap;
    }
}
